package life.kenny.community.service.impl;

import life.kenny.community.dto.NotificationDTO;
import life.kenny.community.dto.PagenationDto;
import life.kenny.community.enums.NotificationStatusEnum;
import life.kenny.community.enums.NotificationTypeEnum;
import life.kenny.community.exception.CustomizeErrorCode;
import life.kenny.community.exception.CustomizeException;
import life.kenny.community.mapper.NotificationMapper;
import life.kenny.community.model.Notification;
import life.kenny.community.model.NotificationExample;
import life.kenny.community.model.User;
import life.kenny.community.service.NotificationService;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Jay
 * @date 2021/12/7 9:45 上午
 */
@Service
public class NotificationServiceImpl implements NotificationService {

    @Autowired
    private NotificationMapper notificationMapper;

    @Override
    public NotificationDTO read(Long id, User user) {
        Notification notification = notificationMapper.selectByPrimaryKey(id);
        if (notification == null) {
            throw new CustomizeException(CustomizeErrorCode.NOTIFICATION_NOT_FOUND);
        }
        //判断通知的人是不是自己
        if (Objects.equals(notification.getReceiver(), user.getId())) {
            throw new CustomizeException(CustomizeErrorCode.READ_NOTIFICATION_FAIL);
        }
        notification.setStatus(NotificationStatusEnum.READ.getStatus());
        notificationMapper.updateByPrimaryKey(notification);

        NotificationDTO notificationDTO = new NotificationDTO();
        BeanUtils.copyProperties(notification, notificationDTO);
        notificationDTO.setOuterId(notification.getOuterid());
        notificationDTO.setTypeName(NotificationTypeEnum.nameOfType(notification.getStatus()));
        return notificationDTO;
    }

    @Override
    public PagenationDto list(Long accountId, Integer page, Integer size) {
        PagenationDto<NotificationDTO> pagenationDto = new PagenationDto<>();

        Integer totalPage;

        NotificationExample notificationExample = new NotificationExample();
        notificationExample.createCriteria()
                .andReceiverEqualTo(accountId);
        int totalCount = notificationMapper.countByExample(notificationExample);
        if (totalCount % size == 0) {
            totalPage = totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }
        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }
        pagenationDto.setPagenation(totalPage, page);

        //size*(page-1)
        Integer offset = size * (page - 1);
        NotificationExample example = new NotificationExample();
        example.createCriteria()
                .andReceiverEqualTo(accountId);
        List<Notification> notifications = notificationMapper.selectByExampleWithRowbounds(example, new RowBounds(offset, size));

        if (notifications.size() == 0) {
            return pagenationDto;
        }
        List<NotificationDTO> notificationDTOS = notifications.stream().map(n -> {
            NotificationDTO dto = new NotificationDTO();
            BeanUtils.copyProperties(n, dto);
            dto.setTypeName(NotificationTypeEnum.nameOfType(n.getType()));
            return dto;
        }).collect(Collectors.toList());
        pagenationDto.setData(notificationDTOS);
        return pagenationDto;
    }

    @Override
    public Integer unreadCount(Long id) {
        NotificationExample example = new NotificationExample();
        example.createCriteria()
                .andReceiverEqualTo(id)
                .andStatusEqualTo(NotificationStatusEnum.UNREAD.getStatus());
        int count = notificationMapper.countByExample(example);
        return count;
    }
}
